/*
 * Galaxium Messenger
 * Copyright (C) 2003-2007 Philippe Durand <draekz@gmail.com>
 * Copyright (C) 2007 Ben Motmans <ben.motmans@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.Collections.Generic;

using Gtk;
using Glade;

using Anculus.Core;

using Galaxium.Core;
using Galaxium.Gui;
using Galaxium.Gui.GtkGui;

namespace Galaxium.Client.GtkGui
{
	public class PreferencesDialog
	{
		[Widget ("PreferencesDialog")] Window _dialog;
		[Widget ("boxPanel")] VBox _boxPanel;
		[Widget ("boxList")] VBox _boxList;
		
		private Dictionary<string, PreferenceCategory> _categories;
		private IPreferenceWidget<Widget> _currentWidget;
		private GalaxiumTreeView _treeView;
		
		public PreferencesDialog ()
		{
			XML gxml = new XML (GladeUtility.GetGladeResourceStream (typeof (PreferencesDialog).Assembly, "PreferencesDialog.glade"), null, null);
			gxml.Autoconnect (this);
			
			_dialog.DeleteEvent += OnWindowDelete;
			(gxml ["close_button"] as Button).Clicked += OnCloseClicked;
			
			GtkUtility.EnableComposite (_dialog);

			_dialog.Icon = IconUtility.GetIcon ("galaxium-preferences", IconSizes.Small);
			
			_treeView = new GalaxiumTreeView ();
			_treeView.Selection.Changed += new EventHandler(TreeViewSelectionChangedEvent);
			_treeView.Reorderable = false;
			_treeView.HeadersVisible = false;
			
			InitColumns ();
			
			ScrolledWindow scrolledWindow = new ScrolledWindow ();
			scrolledWindow.HscrollbarPolicy = PolicyType.Never;
			scrolledWindow.VscrollbarPolicy = PolicyType.Automatic;
			scrolledWindow.Add (_treeView);
			scrolledWindow.ShadowType = ShadowType.In;
			
			_boxList.PackStart (scrolledWindow, true, true, 0);
			//_treeView.WidthRequest = 125;
			
			_categories = new Dictionary<string, PreferenceCategory> ();
			
			foreach (PreferenceWidgetExtension node in AddinUtility.GetExtensionNodes("/Galaxium/Gui/Widgets/Preference"))
			{
				PreferenceCategory category = null;
					
				if (_categories.ContainsKey(node.Category))
					category = _categories[node.Category];
				else
				{
					category = new PreferenceCategory(node.Category);
					category._ref = _treeView.AddRow (category);
					_categories.Add (category.Name, category);
				}
				
				category.AddPlugin (node);
				_treeView.AddRow (category._ref, node);
			}
			
			_treeView.ExpandAll ();
			_treeView.ShowAll();
			
			try
			{
				_treeView.Selection.SelectPath (new TreePath (new int[] { 0, 0 }));
			}
			catch
			{
			}
			
			_dialog.ShowAll ();
		}
		
		protected virtual void InitColumns ()
		{
			TreeViewColumn col = new TreeViewColumn ();
			col.Sizing = TreeViewColumnSizing.Autosize;
			
			CellRenderer renderer = new CellRendererPixbuf ();
			col.PackStart (renderer, false);
			col.SetCellDataFunc (renderer, new TreeCellDataFunc (RenderImage));
			
			renderer = new CellRendererText ();
			col.PackStart (renderer, true);
			col.SetCellDataFunc (renderer, new TreeCellDataFunc (RenderText));
			
			_treeView.AppendColumn (col);
			
			col = new TreeViewColumn ();
			col.PackStart (new ExpanderCellRenderer (), true);
			col.MaxWidth = 16;
			_treeView.InsertColumn (col, 0);
			_treeView.ExpanderColumn = col;
			
		}
		
		private void RenderText (TreeViewColumn col, CellRenderer cell, TreeModel model, TreeIter iter)
		{
			object data = _treeView.GetModelData (iter);
			
			if (data is PreferenceWidgetExtension)
				(cell as CellRendererText).Markup = GLib.Markup.EscapeText ((data as PreferenceWidgetExtension).Name);
			else
				(cell as CellRendererText).Markup = string.Format ("<b>{0}</b>", GLib.Markup.EscapeText ((data as PreferenceCategory).Name));
		}
		
		private void RenderImage (TreeViewColumn col, CellRenderer cell, TreeModel model, TreeIter iter)
		{
			object data = _treeView.GetModelData (iter);
			
			if (data is PreferenceWidgetExtension)
			{
				(cell as CellRendererPixbuf).Pixbuf = (data as PreferenceWidgetExtension).Icon;
				cell.Visible = true;
			}
			else
			{
				(cell as CellRendererPixbuf).Pixbuf = null;
				cell.Visible = false;
			}
		}
		
		private void TreeViewSelectionChangedEvent (object sender, EventArgs args)
		{
			PreferenceWidgetExtension ext = _treeView.Selected as PreferenceWidgetExtension;
			
			if (ext != null)
			{
				if (_currentWidget != null)
				{
					// As we remove the panel from view, shall we save settings here?
					_boxPanel.Remove (_currentWidget.NativeWidget);
				}
				
				IPreferenceWidget<Widget> widget = ext.CreateInstance() as IPreferenceWidget<Widget>;
				
				if (widget != null)
				{
					widget.Initialize();
					
				//	_currentAddin = ext;
					_currentWidget = widget;
					
					// Before we pack the panel in view, perhaps we load settings here?
					_boxPanel.PackStart (widget.NativeWidget, true, true, 0);
				}
				else
				{
				//	_currentAddin = null;
					_currentWidget = null;
				}
			}
		}
		
		private void OnCloseClicked (object sender, EventArgs args)
		{
			ConfigurationUtility.Save ();
			_dialog.Destroy ();
		}

		private void OnWindowDelete (object sender, DeleteEventArgs args)
		{
			ConfigurationUtility.Save ();
			_dialog.Destroy ();
			args.RetVal = false;
		}
	}
}